
//
//  AppDelegate.swift
//  ezyform
//
//  Created by FengMoennig on 11/16/15.
//  Copyright © 2015 Client.Solution Pty Ltd. All rights reserved.


import UIKit
import UserNotifications
import FirebaseMessaging
import Firebase
import IQKeyboardManagerSwift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate {
    
    var isPortrait : Bool = true
    var window: UIWindow?
    let gcmMessageIDKey = "gcm.message_id"
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if #available(iOS 15.0, *) {
            let app = UINavigationBarAppearance()
            app.configureWithOpaqueBackground()
            app.titleTextAttributes = [
                NSAttributedString.Key.foregroundColor: UIColor.black
            ]
            app.backgroundColor = UIColor.white

            UINavigationBar.appearance().scrollEdgeAppearance = app
            UINavigationBar.appearance().standardAppearance = app
            
        }
        //Analytices，用于统计运营数据
        var filePath: String? = ""
        //product
        if APPConfig.isTestFlag == false {
            filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")
        }else{//develop
            filePath = Bundle.main.path(forResource: "GoogleService-Info-Develop", ofType: "plist")
        }
        if let googleServieInfoPath = filePath, let fileopts = FirebaseOptions(contentsOfFile: googleServieInfoPath) {
            FirebaseApp.configure(options: fileopts)
            Messaging.messaging().delegate = self
            UNUserNotificationCenter.current().delegate = self
            
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
            
            application.registerForRemoteNotifications()
        }
        self.window = UIWindow(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: UIScreen.main.bounds.size))
        self.window?.backgroundColor = UIColor(hexStr: Constant.ThemeColorHexStr)
        //支持整个应用程序,这将导致所有弹出窗口使用浅色主题。
        if #available(iOS 13.0, *) {
            self.window?.overrideUserInterfaceStyle = UIUserInterfaceStyle.light
        }
        //1.初始化token，email信息
        LoginService.initAuthorityFromKeychain()
        //2.初始化root controller
        LoginMethodServcie().initRootVC()
        //处理接受到Facebook消息通知启动APP，直接跳转到Facebook链接
        if let dic = launchOptions as NSDictionary?,let userInfo = dic.object(forKey: UIApplication.LaunchOptionsKey.remoteNotification) as? [AnyHashable: Any]{//此处表示点击消息栏中的通知启动的APP
            APPConfig.loginInfo.launchAPPFromNotification = true
            let notification = Notification(name: Notification.Name(rawValue: "messagePushNotification"), object: nil, userInfo: userInfo)
            APPConfig.loginInfo.remoteNotification = notification
        }
        //Open cache
        let urlCache = URLCache.init(memoryCapacity: 4*1024*1024, diskCapacity: 50*1024*1024, diskPath: nil)
        URLCache.shared = urlCache
        //检测网络情况
        DBManager.shared.createDatabase()
        //
        //每次只上传一个数据
        GlobalOperationQueue.maxConcurrentOperationCount = 1
        //键盘显示UITextfield上移
        IQKeyboardManager.shared.enable = true
        IQKeyboardManager.shared.enableAutoToolbar = true
        IQKeyboardManager.shared.shouldResignOnTouchOutside = true//键盘弹出时，点击背景，键盘收回
        ReachabilityHelper.shared.startListener()
        //Crashlytics
        SentryHelper().launchSentry()
        //解决SIGPIPE导致的crash，交给系统处理
        signal(SIGPIPE, SIG_IGN)
        window?.makeKeyAndVisible()
        return true
    }
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
//        print("failed to register for remote notifications:  \(error.localizedDescription)")
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
//        print("device token:\(deviceToken)")
//        let token = NSData(data: deviceToken).description.replacingOccurrences(of: " ", with: "")
//        Messaging.messaging().apnsToken = deviceToken
    }
    //APP在前台时收到FCM发送的消息通知，直接调用这里
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        var userInfo = notification.request.content.userInfo
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // Print full message.
        userInfo["fromForgroundFlag"] = true//APP在前台时收到通知
        pushMessageNotification(userInfo)
        // Change this to your preferred presentation option
        completionHandler([[.sound, .badge]]) // 取消alert不需要弹框
//        completionHandler([[.alert, .sound, .badge]])
    }
    //APP在后台或没有运行时，收到FCM发送的消息通知点击时，调用这里
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        var userInfo = response.notification.request.content.userInfo
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print full message.
        //            print(userInfo)
        //处理远程消息通知,此处加上判断防止由消息通知启动APP后，消息通知再次被处理
        if !APPConfig.loginInfo.launchAPPFromNotification {
            userInfo["fromForgroundFlag"] = false//APP在后台或没有运行时收到通知
            pushMessageNotification(userInfo)
        }
        completionHandler()
    }
    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
        if APPConfig.loginInfo.access_token != "" {
            //刷新Login method，touchid/faceid设置项是否显示（如果更改了系统设置：例如开启指纹或删除指纹）
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "me.loginmethod.setting"), object: nil)
            MessageManager.shared.getUnreadCount()
        }
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }
    
    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        
        if self.isPortrait {
            return UIInterfaceOrientationMask.portrait
        }else{
            return UIInterfaceOrientationMask.landscapeLeft
        }
    }
    func applicationDidReceiveMemoryWarning(_ application: UIApplication) {
        DebugLog("applicationDidReceiveMemoryWarning被执行")
    }
    
    func pushMessageNotification(_ userInfo: [AnyHashable: Any]) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "messagePushNotification"), object: nil, userInfo: userInfo)
    }
}
extension AppDelegate: MessagingDelegate{
    //APP启动后，获取Firebase的注册令牌，将此令牌加入到在Firebase的Cloud Message中即可测试消息通知
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        //保存token, 需要翻墙
        var oldFcmToken = ""
        if let newFcmToken = fcmToken {
            if let data = UserDefaults.standard.object(forKey: "fcmToken") as? String {
                oldFcmToken = data
            }
            APPConfig.loginInfo.fcmToken = newFcmToken
            let accessToken = APPConfig.loginInfo.access_token
            if accessToken != "",newFcmToken != oldFcmToken {//已经登录的用户，且fcm token和缓存的不一样才保存
                UserDefaults.standard.set(APPConfig.loginInfo.fcmToken, forKey: "fcmToken")
                UserDefaults.standard.synchronize()
                let service = NotificationService()
                service.setBlockAfterNetwork { (result, _) in
                    DebugLog(result)
                    MessageManager.shared.getUnreadCount()
                } errorBlock: { (code,msg) in
                    DebugLog("set firebaseToken failed")
                }
                service.setFireBaseToken()
            }
        }
    }
}
